<template>
  <div class="media-upload">
    <el-upload
      class="upload-item"
      action="/commonApi/upload"
      :auto-upload="true"
      :show-file-list="false"
      :before-upload="beforeUpload"
      :on-success="handleSuccess"
      :on-error="handleError"
      :data="{ filePath: 'sys' }"
    >
      <!-- 上传触发器 - 显示上传提示和图标 -->
      <div class="upload-trigger" :class="{ favicon: type === 'favicon' }" v-if="!modelValue">
        <el-icon class="icon"><Plus /></el-icon>
        <div class="upload-text">
          <div class="primary">{{ uploadTitle }}</div>
          <div class="secondary">{{ uploadSubtitle }}</div>
        </div>
      </div>

      <!-- 预览区域 - 显示已上传图片和操作按钮 -->
      <div v-else class="preview-container" :class="{ favicon: type === 'favicon' }">
        <el-image
          class="preview"
          :class="{ favicon: type === 'favicon' }"
          :src="modelValue"
          fit="contain"
        >
          <template #error>
            <div class="image-error">
              <el-icon><Picture /></el-icon>
            </div>
          </template>
        </el-image>
        <div class="preview-actions">
          <el-button type="primary" link size="small" @click.stop="$emit('preview')">
            <el-icon><View /></el-icon>
          </el-button>
          <el-button type="danger" link size="small" @click.stop="$emit('remove')">
            <el-icon><Delete /></el-icon>
          </el-button>
        </div>
      </div>
    </el-upload>
  </div>
</template>

<script setup>
import { computed } from 'vue'
import { ElMessage } from 'element-plus'
import { Plus, Picture, View, Delete } from '@element-plus/icons-vue'

/**
 * 组件属性定义
 */
const props = defineProps({
  /**
   * 文件类型 (logo | favicon)
   * 不同类型有不同的提示和校验规则
   */
  type: {
    type: String,
    default: 'logo',
    validator: (value) => ['logo', 'favicon'].includes(value),
  },

  /**
   * v-model绑定值
   * 存储上传文件的URL或Base64字符串
   */
  modelValue: {
    type: String,
    default: '',
  },
})

/**
 * 组件事件
 */
const emit = defineEmits(['update:modelValue', 'preview', 'remove'])

/**
 * 根据类型显示不同的上传文案
 */
const uploadTitle = computed(() => {
  return props.type === 'logo' ? '点击上传Logo' : '点击上传Favicon'
})

/**
 * 根据类型显示不同的文件限制提示
 */
const uploadSubtitle = computed(() => {
  return props.type === 'logo'
    ? '建议尺寸 200×50px，支持 JPG、PNG、SVG 格式'
    : '建议尺寸 32×32px，支持 ICO、PNG 格式'
})

/**
 * 上传前校验
 * @param {File} file - 上传的文件对象
 * @returns {boolean}
 */
const beforeUpload = (file) => {
  const isImage = file.type.startsWith('image/')
  const maxSize = props.type === 'logo' ? 2 : 1
  if (!isImage) {
    ElMessage.error('只能上传图片文件!')
    return false
  }
  if (file.size / 1024 / 1024 > maxSize) {
    ElMessage.error(`图片大小不能超过 ${maxSize}MB!`)
    return false
  }
  return true
}

/**
 * 上传成功回调
 * @param {Object} res - 后端返回结果
 */
const handleSuccess = (res) => {
  if (res.code === 1 && res.data) {
    emit('update:modelValue', res.data)
    ElMessage.success('上传成功')
  } else {
    ElMessage.error(res.message || '上传失败')
  }
}

/**
 * 上传失败回调
 */
const handleError = (err) => {
  ElMessage.error('上传失败')
}
</script>

<style lang="scss" scoped>
/**
 * 上传组件容器
 */
.media-upload {
  width: 100%;
}

/**
 * 上传组件样式
 */
.upload-item {
  :deep(.el-upload) {
    display: block;
    width: 100%;
    cursor: pointer;
  }

  /**
   * 上传触发区域样式
   */
  .upload-trigger {
    display: flex;
    align-items: center;
    gap: 16px;
    width: 100%;
    height: 100px;
    padding: 20px;
    border: 1px dashed var(--el-border-color);
    border-radius: 12px;
    background-color: var(--el-fill-color-blank);
    transition: all 0.3s;

    &.favicon {
      width: 100%;
    }

    .icon {
      flex-shrink: 0;
      font-size: 24px;
      color: var(--el-text-color-secondary);
      padding: 12px;
      background-color: var(--el-fill-color-light);
      border-radius: 50%;
      transition: all 0.3s;
    }

    .upload-text {
      flex: 1;
      min-width: 0;
      text-align: left;

      .primary {
        font-size: 14px;
        color: var(--el-text-color-primary);
        margin-bottom: 4px;
      }

      .secondary {
        font-size: 12px;
        color: var(--el-text-color-secondary);
        line-height: 1.4;
      }
    }

    &:hover {
      border-color: var(--el-color-primary);
      background-color: var(--el-color-primary-light-9);
      transform: translateY(-2px);
      box-shadow: 0 6px 16px rgba(var(--el-color-primary-rgb), 0.1);

      .icon {
        color: var(--el-color-primary);
        background-color: var(--el-color-primary-light-8);
      }

      .upload-text {
        .primary {
          color: var(--el-color-primary);
        }
      }
    }
  }

  /**
   * 预览容器样式
   */
  .preview-container {
    position: relative;
    width: 100%;
    height: 100px;
    padding: 10px;
    border: 1px solid var(--el-border-color-light);
    border-radius: 12px;
    background-color: var(--el-fill-color-blank);
    overflow: hidden;
    transition: all 0.3s;

    &:hover {
      border-color: var(--el-color-primary);
      box-shadow: 0 6px 16px rgba(var(--el-color-primary-rgb), 0.1);

      .preview-actions {
        opacity: 1;
        transform: translateY(0);
      }
    }

    &.favicon {
      height: 100px;
      width: 100%;

      .preview {
        width: auto;
        max-height: 60px;
      }
    }

    .preview {
      width: 100%;
      height: 100%;
      object-fit: contain;
    }

    .preview-actions {
      position: absolute;
      bottom: 0;
      left: 0;
      right: 0;
      display: flex;
      justify-content: center;
      gap: 16px;
      padding: 12px;
      background: linear-gradient(to top, rgba(0, 0, 0, 0.8), rgba(0, 0, 0, 0));
      opacity: 0;
      transform: translateY(10px);
      transition: all 0.3s;
    }

    .image-error {
      display: flex;
      align-items: center;
      justify-content: center;
      width: 100%;
      height: 100%;
      color: var(--el-text-color-secondary);
      font-size: 24px;
    }
  }
}
</style>
